package com.project.school_flate.serviceimpl.com;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mybatisflex.core.query.QueryWrapper;
import com.project.school_flate.entity.user.UserInfo;
import com.project.school_flate.entity.com.ComPayFlow;
import com.project.school_flate.entity.table.com.ComPayFlowTable;
import com.project.school_flate.mapper.com.ComPayFlowMapper;
import com.project.school_flate.mapper.user.UserInfoMapper;
import com.project.school_flate.service.com.WeiXinPayService;
import com.project.school_flate.util.HttpClientUtil;
import com.project.school_flate.util.HttpUtil;
import com.project.school_flate.util.wechat.KeyPairFactory;
import com.project.school_flate.util.Result.MyPrivatekey;
import com.project.school_flate.util.Result.Result;
import com.project.school_flate.util.system.ComVariableUtil;
import com.project.school_flate.util.wechat.PayDto;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service(value = "WeiXinPayServiceImpl")
@Slf4j
public class WeiXinPayServiceImpl implements WeiXinPayService {

    // 统一下单API_jsApi
    private static final String UNIFIED_ORDER_API ="https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";

    // 统一下单API_App
    private static final String UNIFIED_ORDER_APP ="https://api.mch.weixin.qq.com/v3/pay/transactions/app";

    // 统一下单API_H5
    private static final String UNIFIED_ORDER_H5 ="https://api.mch.weixin.qq.com/v3/pay/transactions/h5";

    // 统一退款API_jsApi
    private static final String UNIFIED_REFUNDS_API ="https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";

    // 获取access_token
    private static final String ACCESS_TOKEN_API ="https://api.weixin.qq.com/cgi-bin/token";

    // 获得jsapi_ticket
    private static final String JSAPI_TICKET_API ="https://api.weixin.qq.com/cgi-bin/ticket/getticket";

    @Autowired
    private ComPayFlowMapper comPayFlowMapper;

    /**
     * 支付接口
     *
     * @param payDto
     * @return
     */
    @Override
    public Result entPay(PayDto payDto) throws Exception {
        UserInfo userInfo = (UserInfo) StpUtil.getSession().get("userInfo");
        if(userInfo == null || StringUtils.isBlank(userInfo.getId())){
            return Result.error("用户不存在");
        }
        Map<String, Object> params = new HashMap<>();
        params.put("appid", ComVariableUtil.getSystemValue("wx_appid"));
        params.put("mchid", ComVariableUtil.getSystemValue("wx_mchId"));
        params.put("description", "零一佰途-办公");
        params.put("out_trade_no", payDto.getOutTradeNo());
        if(StringUtils.isNotBlank(payDto.getAttach())){
            params.put("attach", payDto.getAttach());
        }
        System.out.println("-------------------------------------------");
        System.out.println("传入链接" + payDto.getSceneType());
        System.out.println("-------------------------------------------");
        if(payDto.getSceneType() == 0){
            params.put("notify_url", "https://www.fanshanming.top/api/orderTakeaway/wxPayOrderTakeawayCallback");
        }else if(payDto.getSceneType() == 1){
            params.put("notify_url", "https://www.fanshanming.top/api/shopSaveUser/rechargeShopSaveUserCallback");
        }else if(payDto.getSceneType() == 2){
            params.put("notify_url", "https://www.fanshanming.top/api/userInfo/becomeUserInfoSpecialityDistributionCallback");
        }
//        params.put("notify_url", ComVariableUtil.getSystemValue("wx_mch_cert_resourceurl"));
        Map<String, Object> amount = new HashMap<>();
        amount.put("total",(int)(payDto.getTotalFee() * 100));
        //amount.put("total",payDto.getTotalFee().intValue());
        amount.put("currency","CNY");
        params.put("amount", amount);
        Map<String, Object> payer = new HashMap<>();
        payer.put("openid", userInfo.getWxOptionId());
        params.put("payer", payer);
        String response = doPost(UNIFIED_ORDER_API, JSON.toJSONString(params));
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.where(ComPayFlowTable.COM_PAY_FLOW.TYPE.eq(payDto.getSceneType()));
        queryWrapper.where(ComPayFlowTable.COM_PAY_FLOW.ORDER_ID.eq(payDto.getOutTradeNo()));
        ComPayFlow comPayFlow = comPayFlowMapper.selectOneByQuery(queryWrapper);
        if(comPayFlow == null){
            comPayFlow = new ComPayFlow();
            comPayFlow.setOrderId(payDto.getOutTradeNo());
            comPayFlow.setClientId(userInfo.getId());
            comPayFlow.setCreateTime(new Date());
            comPayFlow.setTotal(payDto.getTotalFee());
            comPayFlow.setState(0);
            comPayFlow.setType(payDto.getSceneType());
            comPayFlowMapper.insert(comPayFlow);
        }
        return Result.ok(JSON.parse(response));
    }

    /**
     * 支付接口_app
     *
     * @param payDto
     * @return
     */
    @Override
    public Result entPayApp(PayDto payDto) throws Exception {
        UserInfo userInfo = (UserInfo) StpUtil.getSession().get("userInfo");
        if(userInfo == null){
            return Result.error("用户不存在");
        }
        Map<String, Object> params = new HashMap<>();
        params.put("appid", ComVariableUtil.getSystemValue("wx_appid"));
        params.put("mchid", ComVariableUtil.getSystemValue("wx_mchId"));
        params.put("description", "零一佰途-办公");
        params.put("out_trade_no", payDto.getOutTradeNo());
        params.put("notify_url", ComVariableUtil.getSystemValue("wx_mch_cert_resourceurl") + "/Order");
        Map<String, Object> amount = new HashMap<>();
        amount.put("total",(int)(payDto.getTotalFee() * 100));
        //amount.put("total",payDto.getTotalFee().intValue());
        amount.put("currency","CNY");
        params.put("amount", amount);
        String response = doPost(UNIFIED_ORDER_APP, JSON.toJSONString(params));
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.where(ComPayFlowTable.COM_PAY_FLOW.TYPE.eq(payDto.getSceneType()));
        queryWrapper.where(ComPayFlowTable.COM_PAY_FLOW.ORDER_ID.eq(payDto.getOutTradeNo()));
        ComPayFlow comPayFlow = comPayFlowMapper.selectOneByQuery(queryWrapper);
        if(comPayFlow == null){
            comPayFlow = new ComPayFlow();
            comPayFlow.setOrderId(payDto.getOutTradeNo());
            comPayFlow.setClientId(userInfo.getId());
            comPayFlow.setCreateTime(new Date());
            comPayFlow.setTotal(payDto.getTotalFee());
            comPayFlow.setState(0);
            comPayFlow.setType(payDto.getSceneType());
            comPayFlowMapper.insert(comPayFlow);
        }
        return Result.ok(JSON.parse(response));
    }

    /**
     * 支付接口_H5
     *
     * @param payDto
     * @return
     */
    @Override
    public Result entPayH5(PayDto payDto) throws Exception {
        UserInfo userInfo = (UserInfo) StpUtil.getSession().get("userInfo");
        if(userInfo == null){
            return Result.error("用户不存在");
        }
        Map<String, Object> params = new HashMap<>();
        params.put("appid", ComVariableUtil.getSystemValue("wx_appid"));
        params.put("mchid", ComVariableUtil.getSystemValue("wx_mchId"));
        params.put("description", "零一佰途-办公");
        params.put("out_trade_no", payDto.getOutTradeNo());
        params.put("notify_url", ComVariableUtil.getSystemValue("wx_mch_cert_resourceurl") + "/Order");
        Map<String, Object> amount = new HashMap<>();
        amount.put("total",(int)(payDto.getTotalFee() * 100));
        //amount.put("total",payDto.getTotalFee().intValue());
        amount.put("currency","CNY");
        params.put("amount", amount);

        Map<String, Object> sceneInfo = new HashMap<>();
        sceneInfo.put("payer_client_ip",payDto.getPayerClientIp());
        Map<String, Object> h5InfoMap = new HashMap<>();
        h5InfoMap.put("type",payDto.getH5InfoType());
        sceneInfo.put("h5_info",h5InfoMap);
        params.put("scene_info", sceneInfo);

        String response = doPost(UNIFIED_ORDER_H5, JSON.toJSONString(params));

        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.where(ComPayFlowTable.COM_PAY_FLOW.TYPE.eq(payDto.getSceneType()));
        queryWrapper.where(ComPayFlowTable.COM_PAY_FLOW.ORDER_ID.eq(payDto.getOutTradeNo()));
        ComPayFlow comPayFlow = comPayFlowMapper.selectOneByQuery(queryWrapper);
        if(comPayFlow == null){
            comPayFlow = new ComPayFlow();
            comPayFlow.setOrderId(payDto.getOutTradeNo());
            comPayFlow.setClientId(userInfo.getId());
            comPayFlow.setTotal(payDto.getTotalFee());
            comPayFlow.setState(0);
            comPayFlow.setType(payDto.getSceneType());
            comPayFlowMapper.insert(comPayFlow);
        }
        return Result.ok(JSON.parse(response));
    }

    /**
     * 回调支付_js_api
     *
     * @param prepayId
     * @return
     */
    @Override
    public Result encryption(String prepayId) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("appId", ComVariableUtil.getSystemValue("wx_appid"));
        long timestamp = System.currentTimeMillis()/ 1000;
        params.put("timeStamp", String.valueOf(timestamp));
        String nonceStr = generateRandomLowercase(8);
        params.put("nonceStr", nonceStr);
        params.put("package", "prepay_id="+prepayId);
        params.put("signType", "RSA");
        String signatureStr = buildMessage(ComVariableUtil.getSystemValue("wx_appid"),timestamp,nonceStr,"prepay_id="+prepayId);
        params.put("paySign", sign(signatureStr.getBytes()));
        return Result.ok(params);
    }

    /**
     * 回调支付_js_app
     *
     * @return
     */
    @Override
    public Result encryptionApp(String prepayId) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("appId", ComVariableUtil.getSystemValue("wx_appid"));
        params.put("partnerid", ComVariableUtil.getSystemValue("wx_mchId"));
        params.put("prepayid", prepayId);
        params.put("package", "Sign=WXPay");
        String nonceStr = generateRandomLowercase(8);
        params.put("nonceStr", nonceStr);
        long timestamp = System.currentTimeMillis()/ 1000;
        params.put("timeStamp", String.valueOf(timestamp));
        String signatureStr = buildMessage(ComVariableUtil.getSystemValue("wx_appid"),timestamp,nonceStr,"prepay_id="+prepayId);
        params.put("paySign", sign(signatureStr.getBytes()));
        return Result.ok(params);
    }

    @Override
    public JSONObject notifyOrder(JSONObject jsonObject) {
        String method = Thread.currentThread().getStackTrace()[1].getMethodName();
        try {
            String key = ComVariableUtil.getSystemValue("wx_mch_apiv3");
            String json = jsonObject.toString();
            System.out.println("报文信息：" + json);
            if(jsonObject.get("summary").equals("支付成功")){
                String associated_data = (String) JSONUtil.getByPath(JSONUtil.parse(json), "resource.associated_data");
                String ciphertext = (String) JSONUtil.getByPath(JSONUtil.parse(json), "resource.ciphertext");
                String nonce = (String) JSONUtil.getByPath(JSONUtil.parse(json), "resource.nonce");
                String decryptData = new AesUtil(key.getBytes(StandardCharsets.UTF_8)).decryptToString(associated_data.getBytes(StandardCharsets.UTF_8), nonce.getBytes(StandardCharsets.UTF_8), ciphertext);
                //验签成功
                JSONObject decryptDataObj = JSONObject.parseObject(decryptData, JSONObject.class);
                System.out.println("解析信息：" + decryptDataObj);
                return decryptDataObj;
            }
        }catch (Exception e){
            log.info("{} ,parms{}, 异常:", method, jsonObject.toJSONString(), e);
        }
        return null;
//        Map<String, String> res = new HashMap<>();
//        res.put("code", "SUCCESS");
//        res.put("message", "成功");
//        return res;
    }

    /**
     * 微信提现
     *
     * @param payDto
     * @return
     */
    @Override
    public Result weixinTransferBat(PayDto payDto) throws Exception {
        //商户号
        String mchid = "";
        //申请商户号的appid或商户号绑定的appid（企业号corpid即为此appid）
        String appId = "";
        //用户在直连商户应用下的用户标示
        String openId = "";
        //商户证书编号
        String wechatPayserialNo = "";
        //商户证书路径（在你本机测试时放你本机路径中的就可以）
        String privatekeypath = "";
        Map<String, Object> postMap = new HashMap<String, Object>();
        //商家批次单号 长度 1~32
        String outNo = IdUtil.getSnowflake(0, 0).nextIdStr();
        postMap.put("appid", appId);
        postMap.put("out_batch_no", outNo);
        //该笔批量转账的名称
        postMap.put("batch_name", "测试转账");
        //转账说明，UTF8编码，最多允许32个字符
        postMap.put("batch_remark", "测试转账");
        //转账金额单位为“分”。 总金额
        postMap.put("total_amount", payDto.getTotalFee());
        //。转账总笔数
        postMap.put("total_num", 1);
        List<Map> list = new ArrayList<>();
        Map<String, Object> subMap = new HashMap<>(4);
        //商家明细单号
        subMap.put("out_detail_no", outNo);
        //转账金额
        subMap.put("transfer_amount", payDto.getTotalFee());
        //转账备注
        subMap.put("transfer_remark", "明细备注1");
        //用户在直连商户应用下的用户标示
        subMap.put("openid", openId);
//		subMap.put("user_name", RsaCryptoUtil.encryptOAEP(userName, x509Certificate));
        list.add(subMap);
        postMap.put("transfer_detail_list", list);

        //发起转账操作
        String resStr = HttpUtil.postTransBatRequest(
                "https://api.mch.weixin.qq.com/v3/transfer/batches",
                JSONObject.toJSONString(postMap),
                wechatPayserialNo,
                mchid,
                privatekeypath);
        return Result.ok();
    }

    String sign(byte[] message) throws NoSuchAlgorithmException, SignatureException, IOException, InvalidKeyException {
        //签名方式
        Signature sign = Signature.getInstance("SHA256withRSA");
        //私钥，通过MyPrivateKey来获取，这是个静态类可以接调用方法 ，需要的是_key.pem文件的绝对路径配上文件名
        sign.initSign(MyPrivatekey.getPrivateKey(ComVariableUtil.getSystemValue("wx_mch_cert_path") + File.separator + "apiclient_key.pem"));
        sign.update(message);
        return Base64.getEncoder().encodeToString(sign.sign());
    }

    /**
     *  按照前端签名文档规范进行排序，\n是换行
     * @param appid
     * @param timestamp
     * @param nonceStr
     * @param prepay_id
     * @return
     */
    String buildMessage(String appid, long timestamp, String nonceStr, String prepay_id) {
        return appid + "\n"
                + timestamp + "\n"
                + nonceStr + "\n"
                + prepay_id + "\n";
    }

    /**
     *  按照前端签名文档规范进行排序，\n是换行
     * @param appid
     * @param timestamp
     * @param nonceStr
     * @param prepay_id
     * @return
     */
    String buildMessage(String appid, long timestamp, String nonceStr) {
        return appid + "\n"
                + timestamp + "\n"
                + nonceStr + "\n";
    }

    /**
     * 发送POST请求（+加签）
     *
     * @param url
     * @param data
     * @return
     * @throws Exception
     */
    private String doPost(String url, String data) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
//        httpPost.setHeader("User-Agent","application/json; charset=utf-8");
        httpPost.setHeader("Accept","application/json");
        httpPost.setHeader("Content-Type","application/json");
        //生成签名
        KeyPairFactory keyPairFactory = new KeyPairFactory();
        KeyPair keyPair = keyPairFactory.createPKCS12(ComVariableUtil.getSystemValue("wx_mch_cert_payKeyMessage"),"Tenpay Certificate", ComVariableUtil.getSystemValue("wx_mchId"));
        long timestamp = System.currentTimeMillis()/ 1000;
        String nonceStr = generateRandomLowercase(8);
        String sign = sign("POST","/v3/pay/transactions/jsapi",timestamp,nonceStr,data,keyPair);
        String token = token(ComVariableUtil.getSystemValue("wx_mchId"),nonceStr,timestamp, ComVariableUtil.getSystemValue("wx_mchcertdata"),sign);//5631A849DA5C89B34BAA5A4E1A21897EEDEC180F
        httpPost.setHeader("Authorization","WECHATPAY2-SHA256-RSA2048 " + token);
        httpPost.setEntity(new StringEntity(data, "UTF-8"));
        CloseableHttpResponse response = httpClient.execute(httpPost);
        HttpEntity entity = response.getEntity();
        String result = EntityUtils.toString(entity, "UTF-8");
        response.close();
        httpClient.close();
        return result;
    }

    /**
     * 生成随机字符串
     * @param length
     * @return
     */
    public static String generateRandomLowercase(int length) {
        String chars = "abcdefghijklmnopqrstuvwxyz";
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            int index = random.nextInt(chars.length());
            sb.append(chars.charAt(index));
        }
        return sb.toString().toUpperCase();
    }

    /**
     * V3  SHA256withRSA 签名.
     *
     * @param method       请求方法  GET  POST PUT DELETE 等
     * @param canonicalUrl 例如  https://api.mch.weixin.qq.com/v3/pay/transactions/app?version=1 ——> /v3/pay/transactions/app?version=1
     * @param timestamp    当前时间戳   因为要配置到TOKEN 中所以 签名中的要跟TOKEN 保持一致
     * @param nonceStr     随机字符串  要和TOKEN中的保持一致
     * @param body         请求体 GET 为 "" POST 为JSON
     * @param keyPair      商户API 证书解析的密钥对  实际使用的是其中的私钥
     * @return the string
     */
    @SneakyThrows
    private static String sign(String method, String canonicalUrl, long timestamp, String nonceStr, String body, KeyPair keyPair)  {
        String signatureStr = Stream.of(method, canonicalUrl, String.valueOf(timestamp), nonceStr, body)
                .collect(Collectors.joining("\n", "", "\n"));
        Signature sign = Signature.getInstance("SHA256withRSA");
        sign.initSign(keyPair.getPrivate());
        sign.update(signatureStr.getBytes());
        return Base64.getEncoder().encodeToString(sign.sign());
    }

    /**
     * 生成Token.
     *
     * @param mchId 商户号
     * @param nonceStr   随机字符串
     * @param timestamp  时间戳
     * @param serialNo   证书序列号
     * @param signature  签名
     * @return the string
     */
    private static String token(String mchId, String nonceStr, long timestamp, String serialNo, String signature) {
        final String TOKEN_PATTERN = "mchid=\"%s\",nonce_str=\"%s\",timestamp=\"%d\",serial_no=\"%s\",signature=\"%s\"";
        // 生成token
        return String.format(TOKEN_PATTERN,mchId,nonceStr, timestamp, serialNo, signature);
    }

    /**
     * 退款接口_jsApi
     *
     * @param payDto
     * @return
     */
    @Override
    public Result refundsPay(PayDto payDto) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("out_trade_no",payDto.getOutTradeNo());
        params.put("out_refund_no",payDto.getOutTradeNo());
        params.put("notify_url",payDto.getRefundsNotifyUrl());
        Map<String, Object> amount = new HashMap<>();
        amount.put("refund",(int)(payDto.getRefundsRefund() * 100));
        amount.put("total",(int)(payDto.getRefundsTotal() * 100));
        amount.put("currency","CNY");
        params.put("amount",amount);
        String response = doPost(UNIFIED_REFUNDS_API, JSON.toJSONString(params));
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.where(ComPayFlowTable.COM_PAY_FLOW.TYPE.eq("订单退款"));
        queryWrapper.where(ComPayFlowTable.COM_PAY_FLOW.ORDER_ID.eq(payDto.getOutTradeNo()));
        ComPayFlow comPayFlow = comPayFlowMapper.selectOneByQuery(queryWrapper);
        if(comPayFlow == null){
            comPayFlow = new ComPayFlow();
            comPayFlow.setOrderId(payDto.getOutTradeNo());
            comPayFlow.setClientId(payDto.getRefundsUserId());
            comPayFlow.setCreateTime(new Date());
            comPayFlow.setTotal(payDto.getRefundsRefund());
            comPayFlow.setState(0);
            comPayFlow.setType(payDto.getSceneType());
            comPayFlowMapper.insert(comPayFlow);
        }
        return Result.ok(JSON.parse(response));
    }

    /**
     * 扫码JS-SDK
     *
     * @param payDto
     * @return
     */
    @Override
    public Result scanCode(String thisUrl) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("appId", ComVariableUtil.getSystemValue("wx_appid"));
        long timestamp = System.currentTimeMillis()/ 1000;
        params.put("timeStamp", String.valueOf(timestamp));
        String nonceStr = generateRandomLowercase(8);
        params.put("nonceStr", nonceStr);
        String signatureStr = buildMessage(ComVariableUtil.getSystemValue("wx_appid"),timestamp,nonceStr);
        params.put("signature", getScanCodeTicket(params.get("appId").toString(),thisUrl,params.get("timeStamp").toString(),params.get("nonceStr").toString()));
        return Result.ok(params);
    }

    /**
     * 扫码JS-SDK
     *
     * @param payDto
     * @return
     */
    public String getScanCodeTicket(String appId,String thisUrl,String timeStamp,String nonceStr) throws Exception {
        //获取access_token
        Map<String,String> map = new HashMap<>();
        map.put("grant_type","client_credential");
        map.put("appid",appId);
        map.put("secret",ComVariableUtil.getSystemValue("wx_secret"));
        String accessJson = HttpClientUtil.doGet(ACCESS_TOKEN_API, map);
        Map<String, String> accessJsonMap = JSONObject.parseObject(accessJson, new TypeReference<HashMap<String, String>>() {
        });
        System.out.println("--------------------------------");
        System.out.println("accessJsonMap : " + accessJsonMap);
        System.out.println("--------------------------------");
        if(StringUtils.isBlank(accessJsonMap.get("access_token"))){
            throw new Exception("获取微信access_token失败");
        }
        String access_token = accessJsonMap.get("access_token");
        //获得jsapi_ticket
        map = new HashMap<>();
        map.put("access_token",access_token);
        map.put("type","jsapi");
        String jsJson = HttpClientUtil.doGet(JSAPI_TICKET_API, map);
        Map<String, String> jsJsonMap = JSONObject.parseObject(jsJson, new TypeReference<HashMap<String, String>>() {
        });
        System.out.println("--------------------------------");
        System.out.println("jsJsonMap : " + jsJsonMap);
        System.out.println("--------------------------------");
        if(StringUtils.isBlank(jsJsonMap.get("ticket"))){
            throw new Exception("获取微信ticket失败");
        }
        System.out.println("--------------------------------");
        System.out.println("thisUrl : " + thisUrl);
        System.out.println("--------------------------------");
        String ticket = jsJsonMap.get("ticket");
        //拼接参数
        String data = "jsapi_ticket=" + ticket + "&noncestr=" + nonceStr + "&timestamp=" + timeStamp + "&url=" + thisUrl;
        System.out.println("--------------------------------");
        System.out.println("jsJson : " + jsJson);
        System.out.println("nonceStr : " + nonceStr);
        System.out.println("timeStamp : " + timeStamp);
        System.out.println("thisUrl : " + thisUrl);
        System.out.println("data : " + data);
        System.out.println("--------------------------------");
        //进行加签
        return SHA1Autograph(data);
    }

    public static String SHA1Autograph(String data) throws Exception {
        try {
            // 创建MessageDigest对象并指定SHA1算法
            MessageDigest md = MessageDigest.getInstance("SHA1");

            // 使用update方法传入要签名的数据
            md.update(data.getBytes());

            // 调用digest方法获取签名结果
            byte[] digest = md.digest();

            // 将字节数组转换为十六进制字符串
            StringBuilder sb = new StringBuilder();
            for (byte b : digest) {
                sb.append(String.format("%02x", b));
            }
            String signature = sb.toString();

            System.out.println("SHA1 Signature: " + signature);
            return signature;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
//        MessageDigest md = MessageDigest.getInstance("SHA-1");
//        md.update(data.getBytes());
//        byte[] digest = md.digest();
//        BigInteger bigInt = new BigInteger(1, digest);
//        String signature = bigInt.toString(16);
//        System.out.println("SHA1 Signature: " + signature);
//        return signature;
    }

}
